﻿namespace NMortgage.UI.Tests.Model
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using NMortgage.UI.Model;

    [TestClass]
    public class MortgageCalculatorTest
    {
        #region Properties

        private MortgageCalculator Subject
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        [TestMethod]
        public void BeginingBalance_In_Payments_Are_Correct()
        {
            // data taken from http://www.mortgagecalculator.org/ using 50,000, 5%, 1 year
            var expected = new double[]
                               {
                                   50000.00,
                                   45927.96,
                                    41838.95,
                                    37732.91,
                                    33609.75,
                                    29469.42,
                                    25311.83,
                                    21136.93,
                                    16944.62,
                                    12734.85,
                                    8507.54,
                                    4262.61,
                               };
            var actual = Subject.Payments.Select(x => x.BeginingBalance).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void EndingBalance_In_Payments_Are_Correct()
        {
            // data taken from http://www.mortgagecalculator.org/ using 50,000, 5%, 1 year
            var expected = new double[]
                               {
                                   45927.96,
                                    41838.95,
                                    37732.91,
                                    33609.75,
                                    29469.42,
                                    25311.83,
                                    21136.93,
                                    16944.62,
                                    12734.85,
                                    8507.54,
                                    4262.61,
                                    0.00
                               };
            var actual = Subject.Payments.Select(x => x.EndingBalance).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void InterestDue_In_Payments_Are_Correct()
        {
            // data taken from http://www.mortgagecalculator.org/ using 50,000, 5%, 1 year
            var expected = new double[]
                               {
                                    208.33,
                                    191.37,
                                    174.33,
                                    157.22,
                                    140.04,
                                    122.79,
                                    105.47,
                                    88.07,
                                    70.60,
                                    53.06,
                                    35.45,
                                    17.76
                               };
            var actual = Subject.Payments.Select(x => x.InterestDue).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void PrincipleDue_In_Payments_Are_Correct()
        {
            // data taken from http://www.mortgagecalculator.org/ using 50,000, 5%, 1 year
            var expected = new double[]
                               {
                                4072.04,
                                4089.01,
                                4106.05,
                                4123.15,
                                4140.33,
                                4157.58,
                                4174.91,
                                4192.30,
                                4209.77,
                                4227.31,
                                4244.93,
                                4262.61,
                               };
            var actual = Subject.Payments.Select(x => x.PrincipleDue).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestInitialize]
        public void TestInitialize()
        {
            var interestParameter = new InterestParameter() { Months = 12, Years = 0 };
            (interestParameter.Distribution as FixedRate).Rate = 5d;
            var profile = new MortgageProfile()
                          {
                              LoanAmount = 50000d,
                              TermLength = 1,
                              PaymentFrequency = PaymentFrequency.Monthly,
                              StartDate = DateTime.Today,
                              InterestRates = new[]
                                              {
                                                  interestParameter,
                                              }
                          };
            Subject = new MortgageCalculator(profile);
        }

        [TestMethod]
        public void Total_Interest_Paid_Is_Calculated_Correctly()
        {
            // from http://www.mortgagecalculator.org
            var expected = 1364.49d;
            var actual = Subject.TotalInterestPaid;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Total_TotalPayments_Is_Calculated_Correctly()
        {
            //from http://www.mortgagecalculator.org
            var expected = 51364.49;
            var actual = Subject.TotalPayments;
            Assert.AreEqual(expected, actual);
        }

        #endregion Methods
    }
}